#include "txr_algo_dlm_seg.h"


#include "../tk_utility/tk_mutex.h"
#include "../txr_algo_dlm_seg/txr_algo_dlm_seg_impl.h"

#include <boost/filesystem.hpp>
#include <QSysInfo>
#include <QDebug>
#include <QCoreApplication>
#include <QDir>

using namespace tk;
static TkMutex g_dlm_mutex;

namespace txr_algo_dlm_seg
{
	typedef TxrAlgoDlmSegImpl* (*FuncCreateDlmSegObj)();
	typedef void(*FuncDeleteDlmSegObj)(TxrAlgoDlmSegImpl*);
	//=====================================================

	TxrAlgoDlmSeg::TxrAlgoDlmSeg()
	{

	}
	TxrAlgoDlmSeg::~TxrAlgoDlmSeg()
	{
		Release();
	}

	tk_bool TxrAlgoDlmSeg::Load(st_dlm_cfg & cfg)
	{
		TkMutexLocker lock(g_dlm_mutex);

		QString app_path = QCoreApplication::applicationDirPath();
		switch (GetDlmType(cfg))
		{
		case DLM_SEG_TYPE_YOLOV5:
			m_lib_dlm = new QLibrary(QDir::toNativeSeparators(app_path + "/txr_algo_dlm_seg_v1"));
			break;
		case DLM_SEG_TYPE_DB:
			m_lib_dlm = new QLibrary(QDir::toNativeSeparators(app_path + "/txr_algo_dlm_seg_v2"));
			break;		
		case DLM_SEG_TYPE_DB_O:
			m_lib_dlm = new QLibrary(QDir::toNativeSeparators(app_path + "/txr_algo_dlm_seg_v2_o"));
			break;
		default:
			return TK_FALSE;
		}

		if (m_lib_dlm)
		{
			if (!m_lib_dlm->load())
			{
				qWarning() << "Library load fail: " << m_lib_dlm->errorString();
				return TK_FALSE;
			}
			FuncCreateDlmSegObj func = (FuncCreateDlmSegObj)(m_lib_dlm->resolve("CreateDlmSegObj"));
			if (func)
			{
				m_dlm_obj = func();
				if (m_dlm_obj)
				{
					return m_dlm_obj->Load(cfg);
				}
			}
		}
		return TK_FALSE;
	}

	void TxrAlgoDlmSeg::Release()
	{
		TkMutexLocker lock(g_dlm_mutex);
		
		if (m_lib_dlm)
		{
			FuncDeleteDlmSegObj func = (FuncDeleteDlmSegObj)(m_lib_dlm->resolve("DeleteDlmSegObj"));
			if (func)
			{
				func(m_dlm_obj);
				m_dlm_obj = TK_NULL_PTR;
			}
			m_lib_dlm->unload();
			m_lib_dlm = TK_NULL_PTR;
		}
	}

	void TxrAlgoDlmSeg::Detect(st_detect_unit * p_unit, tk_int32 size)
	{
		TkMutexLocker lock(g_dlm_mutex);
		if (m_dlm_obj)
		{
			m_dlm_obj->Detect(p_unit, size);
		}
	}
	tk_bool TxrAlgoDlmSeg::IsVaild()
	{
		return m_dlm_obj != TK_NULL_PTR;
	}
	//=============================================================================

	DLM_TYPE TxrAlgoDlmSeg::GetDlmType(st_dlm_cfg & cfg)
	{
		if (cfg.type != DLM_SEG_TYPE_UNKNOWN)
		{
			return cfg.type;
		}
		using namespace boost::filesystem;
		// 检查YOLOV5版本模型文件
		if (exists(path(std::string(cfg.file_path_name) + ".seg1")))
		{
			return DLM_SEG_TYPE_YOLOV5;
		}
		// 检查DB版本模型文件
		else if (exists(path(std::string(cfg.file_path_name) + ".seg2")))
		{
			return DLM_SEG_TYPE_DB;
		}
		// 检查DB_O版本模型文件
		else if (exists(path(std::string(cfg.file_path_name) + ".oseg2")))
		{
			return DLM_SEG_TYPE_DB_O;
		}
		return DLM_SEG_TYPE_UNKNOWN;
	}
}//namespace txr_algo_dlm_seg
